<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Admin\Controller;

use Admin\Data\Common;
use Admin\Entity\Template;
use Admin\Service\TemplateManager;
use Doctrine\ORM\EntityManager;
use Laminas\Config\Reader\Ini;
use Laminas\Filter\Decompress;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\JsonModel;

class TemplateController extends AdminActionController
{
    private $translator;
    private $entityManager;
    private $templateManager;

    private $templatePath;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        TemplateManager $templateManager
    )
    {
        $this->translator       = $translator;
        $this->entityManager    = $entityManager;
        $this->templateManager  = $templateManager;

        $this->templatePath     = 'module/Shop/view/';
    }

    /**
     * 电脑模板
     * @return array[]|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $templatePath   = $this->templatePath . 'pc/';

        $iniReader      = new Ini();
        $templateArray  = [];

        $templateCode   = '';
        $templateCodeArray = [];
        $defaultTemplate= Common::readConfigFile('template')['pcTemplate'];
        if (!empty($defaultTemplate)) {
            $templateCode = str_replace('/', '-', $defaultTemplate);
            if (file_exists($this->templatePath . $defaultTemplate . '/shop/template.ini')) {
                $templateInfo = $iniReader->fromFile($this->templatePath . $defaultTemplate . '/shop/template.ini')['templateInfo'];
                $templateInfo['enable'] = $templateCode;
                $templateArray[] = $templateInfo;
                $templateCodeArray[] = $templateCode;
            }
        }

        if (is_dir($templatePath)) {
            $dirArray = scandir($templatePath);
            foreach ($dirArray as $dirName) {
                if (
                    !in_array($dirName, ['.', '..', '.DS_Store'])
                    && file_exists($templatePath . basename($dirName) . '/shop/template.ini')
                    && $templateCode != 'pc-'.$dirName
                ) {
                    $templateArray[] = $iniReader->fromFile($templatePath . basename($dirName) . '/shop/template.ini')['templateInfo'];
                    $templateCodeArray[] = 'pc-'.$dirName;
                }
            }
        }

        //有更新的模板
        $updateTemplate = [];
        if (!empty($templateCodeArray)) {
            $result = $this->adminCommon()->dbshopApiService('shopTemplateUpdateInfo', ['templateType' => 'pc', 'template' => $templateCodeArray]);
            if (isset($result['result']['updateTemplate'])) $updateTemplate = $result['result']['updateTemplate'];
        }

        return ['templateArray' => $templateArray, 'updateTemplate' => $updateTemplate];
    }

    /**
     * 手机端模板
     * @return array[]
     */
    public function mobileTemplateAction()
    {
        $templatePath   = $this->templatePath . 'mobile/';

        $iniReader      = new Ini();
        $templateArray  = [];

        $templateCode   = '';
        $templateCodeArray = [];
        $defaultTemplate= Common::readConfigFile('template')['mobileTemplate'];
        if (!empty($defaultTemplate)) {
            $templateCode = str_replace('/', '-', $defaultTemplate);
            if (file_exists($this->templatePath . $defaultTemplate . '/shop/template.ini')) {
                $templateInfo = $iniReader->fromFile($this->templatePath . $defaultTemplate . '/shop/template.ini')['templateInfo'];
                $templateInfo['enable'] = $templateCode;
                $templateArray[] = $templateInfo;
                $templateCodeArray[] = $templateCode;
            }
        }

        if (is_dir($templatePath)) {
            $dirArray = scandir($templatePath);
            foreach ($dirArray as $dirName) {
                if (
                    !in_array($dirName, ['.', '..', '.DS_Store'])
                    && file_exists($templatePath . basename($dirName) . '/shop/template.ini')
                    && $templateCode != 'mobile-'.$dirName
                ) {
                    $templateArray[] = $iniReader->fromFile($templatePath . basename($dirName) . '/shop/template.ini')['templateInfo'];
                    $templateCodeArray[] = 'mobile-'.$dirName;
                }
            }
        }

        //有更新的模板
        $updateTemplate = [];
        if (!empty($templateCodeArray)) {
            $result = $this->adminCommon()->dbshopApiService('shopTemplateUpdateInfo', ['templateType' => 'mobile', 'template' => $templateCodeArray]);
            if (isset($result['result']['updateTemplate'])) $updateTemplate = $result['result']['updateTemplate'];
        }

        return ['templateArray' => $templateArray, 'updateTemplate' => $updateTemplate];
    }

    /**
     * 启用模板处理（pc和手机模板）
     * @return mixed
     */
    public function changeShopTemplateAction()
    {
        $templateCode = basename($this->params()->fromQuery('templateCode', ''));
        if (empty($templateCode)) return $this->adminCommon()->toReferer();

        if (file_exists($this->templatePath . str_replace('-', '/', $templateCode) . '/shop/template.ini')) {
            $templateStrArray = explode('-', $templateCode);
            $template = Common::readConfigFile('template');
            if (isset($template[$templateStrArray[0].'Template'])) {
                $template[$templateStrArray[0].'Template'] = $templateStrArray[0] . '/' . $templateStrArray[1];
                Common::writeConfigFile('template', $template);

                $this->adminCommon()->addOperLog($this->translator->translate('模板启用成功!'), $this->translator->translate('模板管理'));
            } else $this->flashMessenger()->addErrorMessage($this->translator->translate('模板启用失败!'));
        }

        return $this->adminCommon()->toReferer();
    }

    /**
     * pc模板在线安装列表
     * @return array|\Laminas\Http\Response
     */
    public function installPcTemplateAction()
    {
        $template = $this->entityManager->getRepository(Template::class)->findBy(['templateType' => 'pc']);
        $templateArray = [];
        if ($template) foreach ($template as $templateValue) {
            $templateArray[] = $templateValue->getTemplateCode();
        }

        $result = $this->adminCommon()->dbshopApiService('shopTemplateList', ['templateType' => 'pc', 'template' => []]);
        if ($result == null) return $this->redirect()->toRoute('service-bind');

        return ['result' => $result, 'templateCodeArray' => $templateArray];
    }

    /**
     * mobile模板在线安装列表
     * @return array|\Laminas\Http\Response
     */
    public function installMobileTemplateAction()
    {
        $template = $this->entityManager->getRepository(Template::class)->findBy(['templateType' => 'mobile']);
        $templateArray = [];
        if ($template) foreach ($template as $templateValue) {
            $templateArray[] = $templateValue->getTemplateCode();
        }

        $result = $this->adminCommon()->dbshopApiService('shopTemplateList', ['templateType' => 'mobile', 'template' => []]);
        if ($result == null) return $this->redirect()->toRoute('service-bind');

        return ['result' => $result, 'templateCodeArray' => $templateArray];
    }

    /**
     * 模板安装
     * @return JsonModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function startInstallTemplateAction()
    {
        $templateCode   = $this->params()->fromPost('templateCode');
        if (!empty($templateCode)) {
            $result = $this->adminCommon()->dbshopApiService('shopTemplateInfo', ['templateCode' => $templateCode]);
            if (
                !$result
                || ($result['code'] == 200 && empty($result['result']))
                || $result['code'] == 400
            ) return new JsonModel(['state' => 'false', 'message' => !empty($result['message']) ? $result['message'] : $this->translator->translate('模板包信息错误，无法进行安装。')]);

            $packageInfo   = $result['result']['templateInfo'];
            $packagePath    = 'data/moduleData/Package';
            $packageDirName = substr($packageInfo['templatePackage'], 0, -4);
            $packageZipFile = $packagePath . '/' .$packageInfo['templatePackage'];
            $sourcePath     = $packagePath.'/'.$packageDirName;

            $downState = $this->adminCommon()->dbshopDownloadPackage('downloadTemplatePackage', ['templateCode' => $templateCode], $packageZipFile);
            if (is_string($downState) && $downState == 'keyError') return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('您的网址无法从公网正常访问，不能进行继续操作。')]);
            if (!$downState) return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('模板包下载失败，无法更新。')]);
            if (md5_file($packageZipFile) != strtolower($packageInfo['packageMd5'])) {
                @unlink($packageZipFile);
                return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('下载的模板包与原始模板包不匹配，无法更新。')]);
            }

            $decompress = new Decompress(['adapter' => 'Zip', 'options' => ['target' => $packagePath]]);
            $decompress->filter($packageZipFile);

            //检查权限
            $allUpdateFiles = Common::getAllFile($sourcePath);
            if (empty($allUpdateFiles)) return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('无可安装文件。')]);
            $checkString    = '';
            foreach ($allUpdateFiles as $updateFile) {
                $coverFile  = ltrim(str_replace($sourcePath, '', $updateFile), DIRECTORY_SEPARATOR);
                $dirPath    = dirname($coverFile);
                if (file_exists($coverFile)) {
                    if (!is_writable($coverFile)) $checkString .= $coverFile . '&nbsp;[<span class="text-red">' . $this->translator->translate('无写入权限') . '</span>]<br>';
                } else {
                    if (!is_dir($dirPath)) @mkdir($dirPath, 0777, true);
                    if (!is_writable($dirPath)) $checkString .= $dirPath . '&nbsp;[<span class="text-red">' . $this->translator->translate('无写入权限') . '</span>]<br>';
                }
            }
            if (!empty($checkString)) return new JsonModel(['state' => 'false', 'message' => $checkString]);

            //进行覆盖
            foreach ($allUpdateFiles as $updateFile) {
                $coverFile  = ltrim(str_replace($sourcePath, '', $updateFile), DIRECTORY_SEPARATOR);
                if (!copy($updateFile, $coverFile)) return new JsonModel(['state' => 'false', 'message' => sprintf($this->translator->translate('无法正常安装模板，请检查%s对应的目录是否有相关权限'), $coverFile)]);
                @chmod($coverFile, 0755);
            }

            //删除更新包及更新文件
            @unlink($packageZipFile);
            Common::deleteDirAndFile($sourcePath);

            $templateInfo = $this->entityManager->getRepository(Template::class)->findOneBy(['templateType' => $packageInfo['templateType'], 'templateCode' => $packageInfo['templateCode']]);
            if ($templateInfo == null) {
                $this->templateManager->addTemplate(['templateName' => $packageInfo['templateName'], 'templateCode' => $templateCode, 'templateVersionNumber' => $packageInfo['templateVersionNumber'], 'templateType' => $packageInfo['templateType']]);
            } else {
                $this->templateManager->editTemplate(['templateVersionNumber' => $packageInfo['templateVersionNumber']], $templateInfo);
            }

            $this->adminCommon()->addOperLog(sprintf($this->translator->translate('模板 %s 安装完成!'), $packageInfo['templateName']), $this->translator->translate('模板管理'));

            return new JsonModel(['state' => 'true', 'message' => $this->translator->translate('安装完成')]);
        }
        return new JsonModel(['state' => 'false', 'message' => $this->translator->translate('信息不完整')]);
    }
}